import { ValidationChain, body } from "express-validator";
import { Request, Response, NextFunction } from "express";
import { decrypt } from "../../common/crypto";
import validate from "../index";
import UserModel from "../../models/user";
import { Op } from "sequelize";

export const usernameValidator = (method: any): ValidationChain => method("username").notEmpty().withMessage("用户名不能为空");

export const passwordValidator = (method: any): ValidationChain =>
  method("password")
    .notEmpty()
    .withMessage("密码不能为空")
    .custom((value: string) => {
      value = decrypt(value);
      if (value.length >= 6) return true;
      throw new Error("密码长度不能小于 6");
    });

export const nameValidator = (method: any): ValidationChain => method("name").notEmpty().withMessage("姓名不能为空");

export const idValidator = (method: any): ValidationChain => method("id").notEmpty().withMessage("id不能为空");

export const statusValidator = (method: any): ValidationChain => method("status").notEmpty().withMessage("状态不能为空");

export const newPasswordValidator = (method: any): ValidationChain =>
  method("newPassword")
    .notEmpty()
    .withMessage("新密码不能为空")
    .custom((value: string) => {
      value = decrypt(value);
      if (value.length >= 6) return true;
      throw new Error("新密码长度不能小于 6");
    });

class UserValidator {
  async login(req: Request, res: Response, next: NextFunction) {
    const validators = [usernameValidator(body), passwordValidator(body)];
    (await validate(validators, req, res)) && next();
  }
  async addUser(req: Request, res: Response, next: NextFunction) {
    const validators = [
      usernameValidator(body)
        .bail()
        .custom(async value => {
          const user = await UserModel.findOne({ where: { username: value } });
          if (!user) return true;
          if (user) {
            throw new Error("账号已经存在");
          }
        }),
      passwordValidator(body),
      nameValidator(body)
        .bail()
        .custom(async value => {
          const user = await UserModel.findOne({ where: { name: value } });
          if (!user) return true;
          if (user) {
            throw new Error("用户名已经存在");
          }
        })
    ];
    (await validate(validators, req, res)) && next();
  }
  async userId(req: Request, res: Response, next: NextFunction) {
    const validators = [idValidator(body)];
    (await validate(validators, req, res)) && next();
  }
  async changeUserStatus(req: Request, res: Response, next: NextFunction) {
    const validators = [idValidator(body), statusValidator(body)];
    (await validate(validators, req, res)) && next();
  }
  async changeUserInfo(req: Request, res: Response, next: NextFunction) {
    const validators = [
      idValidator(body),
      nameValidator(body)
        .bail()
        .custom(async value => {
          const user = await UserModel.findOne({
            where: {
              [Op.and]: [{ name: value }, { id: { [Op.ne]: req.body.id } }]
            }
          });
          if (!user) return true;
          if (user) {
            throw new Error("用户名已经存在");
          }
        }),
      usernameValidator(body)
        .bail()
        .custom(async value => {
          const user = await UserModel.findOne({
            where: {
              [Op.and]: [{ username: value }, { id: { [Op.ne]: req.body.id } }]
            }
          });
          if (!user) return true;
          if (user) {
            throw new Error("账号已经存在");
          }
        })
    ];
    (await validate(validators, req, res)) && next();
  }

  async changePassword(req: Request, res: Response, next: NextFunction) {
    const validators = [newPasswordValidator(body), passwordValidator(body)];
    (await validate(validators, req, res)) && next();
  }
}

export default UserValidator;
